package com.xinsoft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.entity.dto.SysMenuDTO;
import com.xinsoft.entity.dto.SysMenuTreeDTO;
import com.xinsoft.entity.po.SysMenu;
import com.xinsoft.mapper.SysMenuMapper;
import com.xinsoft.service.SysMenuService;
import com.xinsoft.service.SysUserService;
import com.xinsoft.utils.BuildMenuTreeUtils;
import lombok.Synchronized;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
* @author xuhb
* @description 针对表【sys_menu(目录表)】的数据库操作Service实现
* @createDate 2023-04-10 11:34:27
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>
    implements SysMenuService{


    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private SysUserService sysUserService;

    @Override
    public List<SysMenu> listByParam(SysMenuDTO sysMenuDTO){
        List<Integer> type =  Arrays.asList(0, 1, 3);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in(sysMenuDTO.getIsMenu()!=null,"type",type );
        queryWrapper.eq(sysMenuDTO.getTerminal()!=null,"terminal",sysMenuDTO.getTerminal());
        queryWrapper.orderByAsc("order_num");
        return this.list(queryWrapper);
    }

    @Override
    @Synchronized
    public void del(List<Integer> ids) {
        // 删除
        removeByIds(ids);
    }

    @Override
    public SysMenu getMenuById(Integer id){
        SysMenu menu = this.getById(id);
        return menu;
    }

    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public SysMenu addMenu(SysMenuDTO menu) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(menu,sysMenu);
        this.save(sysMenu);
        return sysMenu;
    }

    @Override
    public Set<String> listByUserId(Integer userId) {
        List<String> perms = this.baseMapper.findPermsListByUserId(userId,null);
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms) {
            if (StringUtils.isNotBlank(perm)) {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    @Synchronized
    public SysMenu editSysMenu(SysMenuDTO menu) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(menu,sysMenu);
        sysMenu.setId(menu.getId());
        this.baseMapper.updateById(sysMenu);
        return sysMenu;
    }
    @Override
    public JSONArray getMenuTreeByRoleId(Integer roleId){
        JSONArray result = new JSONArray();
        JSONObject o0 = new JSONObject();
        o0.put("terminal","0");
        o0.put("tree",getSysMenuTree(roleId,0));

        JSONObject o1 = new JSONObject();
        o1.put("terminal","1");
        o1.put("tree",getSysMenuTree(roleId,1));

        JSONObject o2 = new JSONObject();
        o2.put("terminal","2");
        o2.put("tree",getSysMenuTree(roleId,2));

        result.add(o0);
        result.add(o1);
        result.add(o2);
        return result;
    }

    /**
     * 根据角色获取菜单树
     *
     * @param roleId
     * @param terminal
     * @return
     */
    private SysMenuTreeDTO<SysMenuDTO> getSysMenuTree(Integer roleId, Integer terminal){

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("terminal",terminal);
        List<SysMenu> menus = this.list(queryWrapper);
        List<Integer> menuIds = CollectionUtil.newArrayList();
        // 根据roleId查询菜单
        menuIds = this.baseMapper.listMenuIdByRoleId(roleId,terminal);

        List<Integer> temp = menuIds;

        for (SysMenu menu : menus) {
            if (temp.contains(menu.getParentId())) {
                menuIds.remove(menu.getParentId());
            }
        }

        List<SysMenuTreeDTO<SysMenuDTO>> trees = new ArrayList<>();
        for (SysMenu sysSysMenuDTO : menus) {
            SysMenuTreeDTO<SysMenuDTO> tree = new SysMenuTreeDTO<>();
            tree.setId(sysSysMenuDTO.getId().toString());
            tree.setParentId(sysSysMenuDTO.getParentId()==null?null:sysSysMenuDTO.getParentId().toString());
            tree.setText(sysSysMenuDTO.getMenuName());
            Integer menuId = sysSysMenuDTO.getId();
            if(roleId!=null){
                if (menuIds.contains(menuId)) {
                    tree.setState(true);//选中
                } else {
                    tree.setState(false);//未选中
                }
            }
            tree.setOrderNumber(sysSysMenuDTO.getOrderNum());
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        SysMenuTreeDTO<SysMenuDTO> t = BuildMenuTreeUtils.build(trees);
        return t;
    }



    @Override
    public SysMenuTreeDTO<SysMenuDTO> getMenuTreeByUserId(Integer userId,Integer terminal){
            QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.orderByAsc("order_num");
        List<SysMenu> menus = this.list(queryWrapper);
        List<Integer> menuIds = CollectionUtil.newArrayList();
        if(userId!=null){
            // 根据roleId查询菜单
            menuIds = this.baseMapper.listMenuIdByUserId(userId,terminal);
        }

        List<SysMenuTreeDTO<SysMenuDTO>> trees = new ArrayList<>();
        for (SysMenu sysSysMenuDTO : menus) {
            Integer menuId = sysSysMenuDTO.getId();
            if (menuIds.contains(menuId)) {
                SysMenuTreeDTO<SysMenuDTO> tree = new SysMenuTreeDTO<>();
                tree.setId(sysSysMenuDTO.getId().toString());
                tree.setParentId(sysSysMenuDTO.getParentId()==null?null:sysSysMenuDTO.getParentId().toString());
                tree.setText(sysSysMenuDTO.getMenuName());

                tree.setIcon(sysSysMenuDTO.getIcon());
                tree.setIconUrl(sysSysMenuDTO.getIconUrl());
                tree.setType(sysSysMenuDTO.getType());
                tree.setRoutePath(sysSysMenuDTO.getRoutePath());
                tree.setPerms(sysSysMenuDTO.getPerms());
                tree.setTerminal(sysSysMenuDTO.getTerminal());
                tree.setOrderNumber(sysSysMenuDTO.getOrderNum());
                trees.add(tree);
            }
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        SysMenuTreeDTO<SysMenuDTO> t = BuildMenuTreeUtils.build(trees);
        return t;
    }




    @Override
    public SysMenuTreeDTO<SysMenuDTO> getSysTreeDTO(SysMenuDTO sysMenuDTO) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(sysMenuDTO.getTerminal()!=null,"terminal",sysMenuDTO.getTerminal());
        queryWrapper.orderByAsc("order_num");
        List<SysMenu> menus = this.list(queryWrapper);
        List<Integer> menuIdbyroleIds = CollectionUtil.newArrayList();
        if(sysMenuDTO.getRoleId()!=null){
            // 根据roleId查询菜单
            menuIdbyroleIds = this.baseMapper.listMenuIdByRoleId(sysMenuDTO.getRoleId(),sysMenuDTO.getTerminal());


            for (SysMenu menu : menus) {//遍历所有菜单
                if (menuIdbyroleIds.contains(menu.getParentId())) {
                    menuIdbyroleIds.remove(menu.getParentId());
                }
            }
        }

        List<SysMenuTreeDTO<SysMenuDTO>> trees = new ArrayList<>();
        for (SysMenu sysSysMenuDTO : menus) {
            SysMenuTreeDTO<SysMenuDTO> tree = new SysMenuTreeDTO<>();
            tree.setId(sysSysMenuDTO.getId().toString());
            tree.setParentId(sysSysMenuDTO.getParentId()==null?null:sysSysMenuDTO.getParentId().toString());
            tree.setText(sysSysMenuDTO.getMenuName());
            Integer menuId = sysSysMenuDTO.getId();
            if(sysMenuDTO.getRoleId()!=null){
                if (menuIdbyroleIds.contains(menuId)) {
                    tree.setState(true);//选中
                } else {
                    tree.setState(false);//未选中
                }
            }

            tree.setIcon(sysSysMenuDTO.getIcon());
            tree.setIconUrl(sysSysMenuDTO.getIconUrl());
            tree.setType(sysSysMenuDTO.getType());
            tree.setRoutePath(sysSysMenuDTO.getRoutePath());
            tree.setPerms(sysSysMenuDTO.getPerms());
            tree.setTerminal(sysSysMenuDTO.getTerminal());
            tree.setOrderNumber(sysSysMenuDTO.getOrderNum());
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        SysMenuTreeDTO<SysMenuDTO> t = BuildMenuTreeUtils.build(trees);
        return t;
    }

    @Override
    public List<String> getPermsByUserId(Integer userId){
        List<String> perms = this.baseMapper.listUserPerms(userId);
        return perms;
    }
}




